/**
* @file prs_bmp280.c in InsCubeBsp
* @author linfe
* @comment
* Create on 2022/11/29 23:45
* @version 1.0
**/


#include "prs_bmp280.h"



typedef enum {
  BMP280_REGISTER_DIG_T1 = 0x88,
  BMP280_REGISTER_DIG_T2 = 0x8A,
  BMP280_REGISTER_DIG_T3 = 0x8C,

  BMP280_REGISTER_DIG_P1 = 0x8E,
  BMP280_REGISTER_DIG_P2 = 0x90,
  BMP280_REGISTER_DIG_P3 = 0x92,
  BMP280_REGISTER_DIG_P4 = 0x94,
  BMP280_REGISTER_DIG_P5 = 0x96,
  BMP280_REGISTER_DIG_P6 = 0x98,
  BMP280_REGISTER_DIG_P7 = 0x9A,
  BMP280_REGISTER_DIG_P8 = 0x9C,
  BMP280_REGISTER_DIG_P9 = 0x9E,

  BMP280_REGISTER_CHIPID = 0xD0,
  BMP280_REGISTER_VERSION = 0xD1,
  BMP280_REGISTER_SOFTRESET = 0xE0,

  BMP280_REGISTER_CAL26 = 0xE1,  // R calibration stored in 0xE1-0xF0

  BMP280_REGISTER_CONTROL = 0xF4,
  BMP280_REGISTER_CONFIG = 0xF5,
  BMP280_REGISTER_PRESSUREDATA = 0xF7,
  BMP280_REGISTER_TEMPDATA = 0xFA,
} bmp280_reg_t;


/** Oversampling rate for the sensor. */
enum  {
  /** No over-sampling. */
  BMP280_SAMPLING_NONE = 0x00,
  /** 1x over-sampling. */
  BMP280_SAMPLING_X1 = 0x01,
  /** 2x over-sampling. */
  BMP280_SAMPLING_X2 = 0x02,
  /** 4x over-sampling. */
  BMP280_SAMPLING_X4 = 0x03,
  /** 8x over-sampling. */
  BMP280_SAMPLING_X8 = 0x04,
  /** 16x over-sampling. */
  BMP280_SAMPLING_X16 = 0x05
}bmp280_sampling_t;


/** Standby duration in ms */
typedef enum  {
  /** 1 ms standby. */
  BMP280_STANDBY_MS_1 = 0x00u,
  /** 62.5 ms standby. */
  BMP280_STANDBY_MS_63 = 0x01u,
  /** 125 ms standby. */
  BMP280_STANDBY_MS_125 = 0x02u,
  /** 250 ms standby. */
  BMP280_STANDBY_MS_250 = 0x03u,
  /** 500 ms standby. */
  BMP280_STANDBY_MS_500 = 0x04u,
  /** 1000 ms standby. */
  BMP280_STANDBY_MS_1000 = 0x05u,
  /** 2000 ms standby. */
  BMP280_STANDBY_MS_2000 = 0x06u,
  /** 4000 ms standby. */
  BMP280_STANDBY_MS_4000 = 0x07u
}bmp280_standby_duration_t;

/** Filtering level for sensor data. */
enum  {
  /** No filtering. */
  BMP280_FILTER_OFF = 0x00,
  /** 2x filtering. */
  BMP280_FILTER_X2 = 0x01,
  /** 4x filtering. */
  BMP280_FILTER_X4 = 0x02,
  /** 8x filtering. */
  BMP280_FILTER_X8 = 0x03,
  /** 16x filtering. */
  BMP280_FILTER_X16 = 0x04
}bmp280_sensor_filter_t;

/** Operating mode for the sensor. */
typedef enum  {
  /** Sleep mode. */
  BMP280_MODE_SLEEP = 0x00,
  /** Forced mode. */
  BMP280_MODE_FORCED = 0x01,
  /** Normal mode. */
  BMP280_MODE_NORMAL = 0x03,
  /** Software reset. */
  BMP280_MODE_SOFT_RESET_CODE = 0xB6
}bmp280_mode_t;
static void bmp280_write_reg(bmp280_handle_t *dev, uint8_t cmd, uint8_t val) {
    uint8_t dat[2];
    cmd &= ~0x80u;
    dat[0] = cmd;
    dat[1] = val;
    dev_write(dev->dev, dat, 2);
}

static uint16_t bmp280_read_words(bmp280_handle_t *dev, uint8_t reg) {
    uint8_t buffer[2], cmd[2];
    cmd[0] = reg | 0x80u;
    uint16_t rslt;
    dev_write(dev->dev, (uint8_t *)&cmd, 1);
    dev_read(dev->dev, buffer, 2);
    rslt = ((uint16_t)buffer[0] << 8u) + (buffer[1]);
    return rslt;
}

static uint16_t bmp280_read_words_le(bmp280_handle_t *dev, uint8_t reg) {
    uint16_t temp = bmp280_read_words(dev, reg);
    return (temp >> 8u) | (temp << 8u);
}



bmp280_error_t bmp280_init(bmp280_handle_t *dev){
    uint8_t reg;
    uint32_t failure_cnt = 0;
    do {
        reg = BMP280_REGISTER_CHIPID;
        dev_write(dev->dev,&reg,1);
        dev->delay_ms(1);
        dev_read(dev->dev,&reg,1);
        if (dev->trace) {
            dev->trace("Read bmp280 ID:%d\n", (int)reg);
        }
        failure_cnt++;
        dev->delay_ms(1000);
    } while (reg != 0x58 && failure_cnt < 5);
    if (failure_cnt >= 5) {
        dev->trace("Bmp280 ID read failed\n");
        return bmp280_error_id;
    }
    /*读取参数*/
    dev->coeff.dig_P1 = (uint16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P1);
    dev->coeff.dig_P2 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P2);
    dev->coeff.dig_P3 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P3);
    dev->coeff.dig_P4 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P4);
    dev->coeff.dig_P5 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P5);
    dev->coeff.dig_P6 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P6);
    dev->coeff.dig_P7 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P7);
    dev->coeff.dig_P8 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P8);
    dev->coeff.dig_P9 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_P9);

    dev->coeff.dig_T1 = (uint16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_T1);
    dev->coeff.dig_T2 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_T2);
    dev->coeff.dig_T3 = (int16_t)bmp280_read_words_le(dev, BMP280_REGISTER_DIG_T3);

    uint8_t ctrl = (BMP280_SAMPLING_X2 << 5u) | (BMP280_SAMPLING_X16 << 2) | BMP280_MODE_NORMAL;
    bmp280_write_reg(dev, BMP280_REGISTER_CONTROL, ctrl);
    uint8_t cfg = BMP280_STANDBY_MS_1 << 5u | BMP280_FILTER_X16 << 2u | 0x00u;
    bmp280_write_reg(dev, BMP280_REGISTER_CONFIG, cfg);
    return bmp280_ok;

}

bmp280_error_t bmp280_read(bmp280_handle_t *dev, press_data_t *data){
/*    int32_t var1, var2;
    int32_t adc_t = bmp280_read_words(dev, BMP280_REGISTER_TEMPDATA);
    adc_t <<= 8u;
    adc_t |= Bmp280SpiReadReg(dev, BMP280_REGISTER_TEMPDATA + 2);
    adc_t >>= 4u;
    var1 = ((((adc_t >> 3u) - ((int32_t)coeff.dig_T1 << 1u))) *
        ((int32_t)coeff.dig_T2)) >> 11u;
    var2 = (((((adc_t >> 4u) - ((int32_t)coeff.dig_T1)) *
        ((adc_t >> 4u) - ((int32_t)coeff.dig_T1))) >> 12u) *
        ((int32_t)coeff.dig_T3)) >> 14u;
    t_fine = var1 + var2;
    float T = (t_fine * 5 + 128) >> 8u;
    return T / 100.0;*/
    return bmp280_ok;
}